package com.wutianyi.datastore;

import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;

/**
 * @author hanjiewu
 * 
 */
public class Entity
{
    private final static String DEFAULT_KIND = "kind";
    /**
     * 类型
     */
    Key key;

    /**
     * 只支持基本类型
     */
    private Map<String, Object> properties = new HashMap<String, Object>();

    private Map<String, Boolean> propertiesInIndexes;

    private Map<String, Object> originalIndexProperties;

    public Entity()
    {
        this(DEFAULT_KIND);
    }

    public Entity(String kind)
    {
        this(kind, 0);
    }

    public Entity(String kind, int id)
    {
        this.key = KeyFactory.getKey(kind);
    }

    public Entity(String kind, String key)
    {
        this.key = KeyFactory.getKey(kind, key);
    }

    public void setProperty(String property, Object value, boolean isIndex)
    {
        setProperty(property, value);
        if (isIndex)
        {
            initPropertiesInIndexes();
            propertiesInIndexes.put(property, isIndex);
        }
    }

    public Entity addProperty(String property, Object value, boolean isIndex)
    {
        setProperty(property, value, isIndex);
        return this;
    }

    public Entity addProperty(String property, Object value)
    {
        setProperty(property, value);
        return this;
    }

    public void setPropertyIndex(String property, boolean isIndex)
    {
        initPropertiesInIndexes();
        propertiesInIndexes.put(property, isIndex);
    }

    public boolean isPropertyIndex(String property)
    {
        if (null != propertiesInIndexes)
        {
            Boolean isIndex = propertiesInIndexes.get(property);
            if (null != isIndex)
            {
                return isIndex;
            }
        }
        return false;

    }

    public Map<String, Object> getProperties()
    {
        return properties;
    }

    public void setProperties(Map<String, Object> properties)
    {
        this.properties = properties;
    }

    public Map<String, Boolean> getPropertiesInIndexes()
    {
        return propertiesInIndexes;
    }

    public void setPropertiesInIndexes(Map<String, Boolean> propertiesInIndexes)
    {
        this.propertiesInIndexes = propertiesInIndexes;
    }

    private void initPropertiesInIndexes()
    {
        if (null == propertiesInIndexes)
        {
            propertiesInIndexes = new HashMap<String, Boolean>();
        }
    }

    public void setProperty(String property, Object value)
    {
        if (null == value)
        {
            throw new NullPointerException("Property Value Must Not Null!");
        }
        properties.put(property, value);
    }

    public Object getProperty(String property)
    {
        return properties.get(property);
    }

    public Enumeration<String> properties()
    {
        final Iterator<String> itr = properties.keySet().iterator();
        return new Enumeration<String>()
        {

            @Override
            public boolean hasMoreElements()
            {
                return itr.hasNext();
            }

            @Override
            public String nextElement()
            {
                return itr.next();
            }
        };
    }

    public Map<String, Object> getOriginalIndexProperties()
    {
        return originalIndexProperties;
    }

    public void setOriginalIndexProperties(Map<String, Object> originalIndexProperties)
    {
        this.originalIndexProperties = originalIndexProperties;
    }

    public String getKind()
    {
        return key.getKind();
    }

    public Iterator<Object> iterValues()
    {
        return properties.values().iterator();
    }

    public String getKey()
    {
        return key.getKey();
    }

    public void setId(int id)
    {
        key.setId(id);
    }

    @Override
    public String toString()
    {
        StringBuilder builder = new StringBuilder();
        builder.append("Entity: id: ");
        builder.append(key.getId());
        builder.append(", key: " + key.getKey());
        builder.append('\n');
        builder.append('{');
        builder.append('\n');
        for (Entry<String, Object> entry : properties.entrySet())
        {
            builder.append('\t');
            builder.append(entry.getKey());
            builder.append(": ");
            builder.append(entry.getValue());
            builder.append("\r\n");
        }
        builder.append('}');

        return builder.toString();
    }
}
